/**
 * @Author your name
 * @Date 2021-03-04 10:48:22
 * @LastEditTime 2021-03-04 15:15:42
 * @LastEditors Please set LastEditors
 * @Description In User Settings Edit
 * @FilePath \fed-e-task-04-06\code\rxjs-tutorial\src\index.js
 */
import { BehaviorSubject, forkJoin, from, fromEvent, interval, Observable, of, range, ReplaySubject, Subject } from 'rxjs'
import { concatMap, debounceTime, distinctUntilChanged, distinctUntilKeyChanged, map, pluck, switchMap, take, takeUntil, takeWhile, throttleTime } from 'rxjs/operators'
import axios from 'axios'

// // 创建可观察对象 observable
// const observable = new Observable(function (observer) {
//     let index = 0
//     let timer = setInterval(() => {
//         observer.next(index++)
//         if (index === 3) {
//             // observer.complete()
//             observer.error('错误信息')
//             observer.next(index++) // 已终止 不会执行
//             clearInterval(timer)
//         }
//     }, 2000);
// })

// // 创建观察者 observer
// const observer = {
//     next: function (value) {
//         console.log(value)
//     },
//     complete: function () {
//         console.log('终止了')
//     },
//     complete: function (error) {
//         console.log(error)
//     }
// }

// // 订阅 将可观察对象和观察者连接起来
// observable.subscribe(observer)


// const observable = new Observable(function (observer) {
//     console.log('Hello') // 执行了 3 次
// })

// observable.subscribe()
// observable.subscribe()
// observable.subscribe()


// const demoSubject = new Subject()

// demoSubject.subscribe({ next: console.log })
// demoSubject.subscribe({ next: console.log })

// setTimeout(() => {
//     demoSubject.next('hello')
// }, 2000);


// const demoBehavior = new BehaviorSubject('默认值')

// demoBehavior.subscribe({ next: console.log }) // 默认值 // 新值

// demoBehavior.next('新值')


// const rSubject = new ReplaySubject()

// rSubject.subscribe({ next: console.log }) // hello

// rSubject.next('hello')

// setTimeout(() => {
//     rSubject.subscribe({ next: console.log }) // hello
// }, 3000);


// range(1, 10).subscribe(console.log) // 1 2 3 ... 10

// range(1, 10)
//     .pipe(map(n => 10 * n))
//     .subscribe(console.log) // 10 20 30 ... 100

// from(['a', 'b', 'c']).subscribe(console.log) // a // b // c

// function p () {
//     return new Promise(resolve => {
//         setTimeout(() => {
//             resolve({ a: 1 })
//         }, 2000);
//     })
// }

// from(p()).subscribe(console.log) // {a: 1}


// http://localhost:3005/goods
// http://localhost:3005/category

// axios.interceptors.response.use(responese => responese.data)

// forkJoin({
//     goods: from(axios.get('http://localhost:3005/goods')),
//     category: from(axios.get('http://localhost:3005/category'))
// }).subscribe(console.log) // { goods: {...}, category: {...}}


// const button = document.getElementById('btn')

// fromEvent(button, 'click')
//     .pipe(pluck('target')) 
//     .subscribe(console.log) // <button id="btn">按钮</button>


// interval(1000).subscribe(console.log) // 0 1 2 ...

// const button = document.getElementById('btn')

// fromEvent(button, 'click')
//     .pipe(switchMap(event => interval(1000)))
//     .subscribe(console.log) // 数据流切换成 interval 的数据流


// range(1, 10)
//     .pipe(takeWhile(n => n < 3))
//     .subscribe(console.log) // 1 2

// const button = document.getElementById('btn')

// // 当鼠标在页面中移动时会不断发出数据流
// // 当鼠标点击事件时数据流会停止发出主数据流
// fromEvent(document, 'mousemove')
//     .pipe(takeUntil(fromEvent(button, 'click'))
//     .subscribe(console.log)


// fromEvent(document, 'click')
//     .pipe(debounceTime(2000)) // 两秒内没有数据源，只输出最后一次数据流
//     .subscribe(console.log)


// of('a', 1, true, {}, []).subscribe(console.log) // 'a' 1 true {} []

// of(1, 1, 2, 2, 3, 4)
//     .pipe(distinctUntilChanged())
//     .subscribe(console.log) // 1 2 3 4


// 元素拖拽
// const box = document.getElementById('box')

// // 添加数据流 获取元素点击
// fromEvent(box, 'mousedown')
//     .pipe(
//         // 计算鼠标位于元素的坐标
//         map(event => ({
//             distanceX: event.clientX - event.target.offsetLeft,
//             distanceY: event.clientY - event.target.offsetTop
//         })),
//         // 切换数据流 获取移动事件
//         switchMap(({distanceX, distanceY}) => 
//             fromEvent(document, 'mouseover')
//                 .pipe(
//                     // 计算当前元素的坐标值
//                     map(event => ({
//                         left: event.clientX - distanceX,
//                         top: event.clientY - distanceY
//                     })),
//                     // 如果元素有输入 mouseup 数据流则终止主数据流
//                     takeUntil(fromEvent(box, 'mouseup'))
//                 )
//         )
//     )
//     // 修改元素坐标值
//     .subscribe(({left, top}) => {
//         box.style.left = left + 'px'
//         box.style.top = top + 'px'
//     })
// box.onmousedown = function (event) {
//     let distanceX = event.clientX - event.target.offsetLeft 
//     let distanceY = event.clientY - event.target.offsetTop

//     document.onmouseover = function (event) {
//         let left = event.clientX - distanceX
//         let top = event.clientY - distanceY
//         box.style.left = left + 'px'
//         box.style.top = top + 'px'
//     }
//     box.onmouseup = function () {
//         document.onmouseover = null
//     }
// }


// 搜索
// const search = document.getElementById('search')

// fromEvent(search, 'keyup')
//     .pipe(
//         debounceTime(1000), // 防抖
//         map(event => event.target.value),
//         distinctUntilChanged(), // 与上次数据流相同则跳过
//         // 切换数据流
//         switchMap(keyword => 
//             from(axios.get(`https://j1sonplaceholder.typicode.com/posts?q=${keyword}`))
//         )
//     )
//     .subscribe(console.log)


// 串联请求
const button = document.getElementById('btn')

fromEvent(button, 'click')
    .pipe(
        concatMap(event => from(axios.get('http://localhost:3005/token'))),
        concatMap(token => from(axios.get('http://localhost:3005/userInfo')))
    )
    .subscribe(console.log)